// 官网代码全部删除了,在main.js里面有,7月9号----------------7月9号---------
// 7月9号----------------7月9号----------------------------7月9号----------------7月9号---------
// 导入路由 ruoter  main.js里面 import '@/permission' 已经导包执行了,所以这里不需要暴露出去
// Element提示插件
import { Message } from 'element-ui'
import router from './router'
// 导入store仓库
import store from './store/index.js'
import permission from './store/modules/permission'
// 导入删除token的工具函数removeToken
import { removeToken } from './utils/auth'

// 白名单的作用:为了更加方便的管理不需要登录的页面
// (一般项目中不需要登陆的页面,不单单只有一个,项目有些页面是不需要登陆,又没有token的,)--不需要登陆的页面/放走通行
// 以前的写法, if(路径==="/login"||路径==='/404'||路径==='/register')
// 所以上面得写法如果出现很多很多页面不需要登陆,那么这样写法就代码冗余了
// 所以为了简化代码,解决代码冗余的问题,就声明`数组`,里面发了可以访问的`路径`,这叫做叫做白名单

// 声明白名单,就是一个数组,不需要登陆的页面,也没token的
// 这个声明不要放在beforeEach里面,那么每次执行都会重新声明一次,没有必要(让费性能)放在外面声明一次就行了
const whitList = ['/login', '/404']

// 7月9号----------------7月9号---------7月9号-------------------
// 头条项目的导航守卫是定义在 router/index.js里面的, 目前这个项目permission.js默认写好了
// 判断是的逻辑是在页面切换的时候,或者是路由切换的时候执行,所以需要定义在,导航守卫里面
// 第一,注册导航守卫
router.beforeEach(async(to, from, next) => {
  // 打印出来能拿到token 762b5416-8b71-491a-8392-cb15a557bd5c
  // console.log('getters里面的token', store.getters.token)
  // 登录状态判断分析
  const _token = store.getters.token
  if (_token) {
    // 7月9号----------------7月9号---------7月9号-------------------
    // 判断用户信息(就是判断token对错)
    // 这里打印的是有一个空对象,但是空对象去判断布尔值是true,所以需要点出里面的值
    // 在layout/Navbar.vue里面写上测试代码后,this.$store.dispatch('user/getUserInfo')
    // 然后再store/modules/user.js是可以打印出来获取到用户信息数据的,在getUserInfo方法里面console.log('res', res)
    // store/modules/user.js里面打印出来的数据里面有一个 userId: "604f764971f93f3ac8f365cb"
    // userId去判断语义性不是很强,(那么可以把用户信息保存在字段里面,在store/getters.js里面去定义这个字段isLogin)
    // console.log('userInfo', store.getters.userInfo)
    // 111,判断,有token,有用户信息,说明没有问题,那就放走,但是不需要去login页面
    // 而是去首页'/'
    if (store.getters.userInfo.userId && to.path === '/login') {
      return next('/')
    }
    // 222,到了这里说明去的不是登陆页,并且用户信息又存在
    // 判断,有token,有用户信息,说明没有问题,那就放走,
    // store.getters.userInfo.userId  改成了store/getters.js里面去定义这个字段isLogin,7月10号修改
    if (store.getters.isLogin) {
      return next()
    }
    // 333,用户信息不存在,但是token存在(那就尝试获取一下用户信息)
    // 因为这里是一个异步的操作,所以需要加一个 async router.beforeEach(async(to, from, next)
    // 重点,try里面出错了,才会执行到catch里面
    try {
      // await是会柱塞代码执行,所以一定是等获取到用户信息的时候,才会执行它下面的代码
      await store.dispatch('user/getUserInfo')
      // 7月23号--------------------------------7月23号--------------------------------
      // 改造,之前是在登陆的时候,因为所有的路由都配了,登陆成功就能访问,但是之前只是配置了一些基础路由
      // 那当用户正常的获取完用户信息之后,还需要做一件事件,就需要筛选出当前这个用户可以访问哪些路由信息
      // 然后再把他放走,那问题就来了,在哪里获取到了用户信息呢???这里就是取那用户信息await store.dispatch('user/getUserInfo')
      // 所以代码能执行到这里,说明用户信息获取到了,然后信息拿到后,里面就有字段就有路由的信息了
      // (在控制台的uesr/setUserInfo打开后,点击vuex里面的user/userInfo/roles/menus里面有"employees""setting""permissions"...)
      // 所以拿到这个用户信息后,就可以做路由筛选了,路由信息放的位置再src\store\modules\permission.js,的action方法里面
      // 就在里面去筛选出用户可以访问的路由,然后设置一下,(核心的方法就是addRoutes,在src\router\index.js里面添加了这方法,linlin)
      // 因为不加这个方法,用户是访问不了的,然后再当前这个页面去调用这个action的方法,然后再放走
      // 调用permission里面的filterRoutes方法
      await store.dispatch('permission/filterRoutes')
      // 7月23号--------------------------------7月23号--------------------------------
      // console.log('用户信息获取成功')
      // console.log('userInfo', store.getters.userInfo)
      if (to.path === '/login') {
        // 判断,如果是在登陆页面拿到用户信息,那就去首页
        return next('/')
      }
      // 代码执行到这里,说明不是去登陆页面,那就放走
      // return next()
      // 调用了`addRoutes`方法之后`next`中传入`to`可以避免白屏问题
      // 网站https://juejin.cn/post/6844903478880370701
      // 这是vue emelent admin 作者写的方法,
      // 7月23号--------------------------------7月23号--------------------------------
      return next(to)
      // 完成了404的bug后,去到前其他的页面刷新就出现白屏的情况??另外一个bug了
      // 分析:::白屏的情况,就是路由里面的一个问题,(除了首页,)当在其他页面一刷新,就会去到一个导航守卫里面,src\permission.js里面,
      // 当每次刷新, 就会进入(登录状态判断分析)的这段代码里面,当刷新后,token是存在的,但是vuex没有,因为vuex不是常驻的,token是常驻的
      // 所以,<判断用户信息(就是判断token对错)>if (store.getters.userInfo.userId && to.path === '/login')和判断  if (store.getters.isLogin) 这两个判断是进不去,
      // 因为还没有登陆!
      // 那代码在执行,就跑到try里面去了,就获取到了用户的数据,并且筛选了,所以按常理来说是正常可以进过的,,所以代码正常这样写是没问题,这是路由的一个bug吧,
      // 分析,就是当用addRoutes的方式加了(  await store.dispatch('permission/filterRoutes')判断,),就不能直接 return next(),直接next()就是放走,所以它不会去读取
      // 筛选后加进去的路由信息,,解决方案, 给return next()设置一个 to, 这个to的作用,就是重新走一下这个判断逻辑,就能确保这路由加载完毕,然后就能行了
      // 7月23号----------上面的 return next(to)分析----------------------7月23号--------------------------------
    } catch (error) {
      // 代码能执行到这里,说明是token是存在的,但是token有问题
      // console.log('请求出错啦')
      // console.dir(error)
      // token有问题(就提示,删除,去登陆页面)
      // removeToken()
      // ------------------------------------------
      // 7月10号-----------------------7月10号-----------------------
      // 之前写的是只能删除本地Cookie存储的token,但是用户信息和用户token没有删除
      // 分析:这里删除本地的token后和Cookie的token后,页面的错误提示就只有一个了,是因为当本地Cookie也有token,然后是错误的token数据,那么就会执行一次登录状态判断分析的整个代码
      // 然后此时vuex仓库就存储了一个token,所以如果只是删除了本地的Cookie的token,是不够的,因为仓库存储了一个token,那么就会重新在执行一下登录状态判断分析的整个代码
      // 就执行了两次哦,所以出现两次,两个token全部删除才提示一次
      store.dispatch('user/logout')

      // 提示用户
      Message.error('请重新登陆')
      // 去登陆页面
      // return next('/login') // 这里不能直接这样写,会有一个bug,如果目前用户就在登陆页面,然后的代码又是去到登陆页面,那么就会出现一个无限循序了(就出现一直提示去登陆了)
      if (to.path === '/login') {
        // 判断是登陆页面,就直接放走
        return next()
      }
      // 不是登陆页面,就要打回到登陆页面
      // 7月10号--------改动---------------7月10号-----------------------
      // 注意,在控制台vue里面的Components里面的login里面data里面有redirect:"/dashboard"这个地址(来源的路径)
      // redirect是项目默认就有的
      // ?redirect=' + to.fullPath  在url中携带目标地址
      // fullPath可以获取全部的地址比如,/xxx/?key=value
      // path只可以获取,/xxx
      return next('/login?redirect=' + to.fullPath)
    }
    // ---------------------------------------------------------------
    // token判断,有token(但是还没有判断token对错)
    // console.log(to.path) // 到了什么页面(比如访问了login,那么打印的就是 /login)
    // 判断,有token的情况下访问的是login页面,那么就没有这个必要(就不让用户访问login页面),所以去首页return next('/')
    // if (to.path === '/login') {
    //   return next('/')
    // }
    // // 代码能执行到这里,说明不是登陆页,那就直接放走
    // return next()
  }
  // 这里是没有token的判断,那就是不需要登陆的页面,就是白名单的逻辑了
  // includes方法是判断是否存在这个值, 存在是true, 不存在是false
  if (whitList.includes(to.path)) {
    // 不需要的登陆的页面就放走,有没有token都无所谓
    return next()
  }
  // 如果不在白名单中,并且又没有_token,那就去登陆页
  next('/login')
})
